package ingest.blog.icwsm.icwsmutils;

import ingest.blog.icwsm.icwsmutils.Constants.Language;
import ingest.blog.icwsm.icwsmutils.Constants.SourceType;
import ingest.blog.icwsm.protoutils.ProtoStreamUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.spinn3r.api.protobuf.ContentApi.Entry;


/**
 * Utilities for interacting with the dataset.
 * @author niels
 *
 */
public class DatasetUtils
{
	/**
	 * The year and month in the file structure
	 */
	public static String ICWSMstructure = File.separator + "2011";

	
	/**
	 * Get a specific Entry from a protosteam file.
	 * @param protostream The protostream file.
	 * @param entryNumber The entry to get.
	 * @return The specified entry.
	 * @throws FileNotFoundException
	 */
	public static Entry getEntryFromProtostream(String protostream, int entryNumber) throws FileNotFoundException
	{		
		return getEntryFromProtostream(new File(protostream), entryNumber);
	}

	/**
	 * Get a specific Entry from a protosteam file.
	 * @param protostream The protostream file.
	 * @param entryNumber The entry to get.
	 * @return The specified entry.
	 * @throws FileNotFoundException
	 */
	public static Entry getEntryFromProtostream(File protostream, int entryNumber) throws FileNotFoundException
	{		
		return ProtoStreamUtils.read(protostream).get(entryNumber);
	}
	
	
	/**
	 * Gets all the filenames in the dataset which are assumed to be of a certain type of content.
	 * The function assumes that the original ICWSM file structure is present, i.e., 2011->01->14->WEBLOGS->us
	 * @param publisherType The type of publisher to read
	 * @param language The language to get
	 * @param baseDir The directory where the "2011" folder is located.
	 * @return A list of all the filenames that match the criteria
	 * @throws IOException 
	 */
	public static List<String> getFileNamesFor(SourceType publisherType, Language language, File baseDir) throws IOException
	{
		List<String> fileList = new ArrayList<String>();
		File dir = new File(baseDir.toString() + ICWSMstructure);		
		if (dir.exists())			
		{
			for (String month : dir.list())
			{
				File dateDir = new File(dir.toString() + File.separator + month);
				if (dateDir.exists())
				{
					for (String date : dir.list())
					{
						File langDir = new File(dir.toString() + File.separator + date + File.separator + publisherType.toString() + File.separator + language.toString());
						if (langDir.exists())
						{
							System.out.println("Traversing into " + langDir);
							for (String file : langDir.list())
							{						
								fileList.add(langDir.toString() + File.separator + file);
							}				
						}
						else
							throw new IOException("Directory " + langDir.toString() + " does not exist.");
					}
				}
				else
					throw new IOException("Directory " + dateDir.toString() + " does not exist.");
			}
		}
		else
			throw new IOException("Directory " + dir.toString() + " does not exist.");
		Collections.sort(fileList);
		return fileList;
	}
	/**
	 * Gets all the filenames in the dataset which are assumed to be of a certain type of content.
	 * The function assumes that the original ICWSM file structure is present, i.e., 2011->01->14->WEBLOGS->us
	 * @param publisherType The type of publisher to read
	 * @param language The language to get
	 * @param baseDir The directory where the "2011" folder is located.
	 * @return A list of all the filenames that match the criteria
	 * @throws IOException 
	 */
	public static List<String> getFileNamesFor(SourceType publisherType, Language language, String baseDir) throws IOException
	{
		return getFileNamesFor(publisherType, language, new File(baseDir));
	}


	/**
	 * Gets all the filenames in the dataset which are assumed to be of a certain type of content.
	 * The function assumes that the original ICWSM file structure is present, i.e., 2011->01->14->WEBLOGS->us
	 * @param publisherType The type of publisher to read
	 * @param language The language to get
	 * @param month The month for which to get data (e.g., 01 or 02)
	 * @param day The day for which to get data (e.g., 13)
	 * @param baseDir The directory where the "2011" folder is located.
	 * @return A list of all the filenames that match the criteria
	 * @throws IOException 
	 */
	public static List<String> getFileNamesFor(SourceType publisherType, Language language, String month, String day, File baseDir) throws IOException
	{
		List<String> fileList = new ArrayList<String>();
		File dir = new File(baseDir.toString() + ICWSMstructure);
		if (dir.exists())
		{
			File langDir = new File(dir.toString() + File.separator + month + File.separator + day + File.separator + publisherType.toString() + File.separator + language.toString());
			if (langDir.exists())
			{
				System.out.println("Traversing into " + langDir);
				for (String file : langDir.list())
				{						
					fileList.add(langDir.toString() + File.separator + file);
				}				
			}
			else
				throw new IOException("Directory " + langDir.toString() + " does not exist.");
		}
		else
			throw new IOException("Directory " + dir.toString() + " does not exist.");
		Collections.sort(fileList);
		return fileList;
	}
	/**
	 * Gets all the filenames in the dataset which are assumed to be of a certain type of content.
	 * The function assumes that the original ICWSM file structure is present, i.e., 2011->01->14->WEBLOGS->us
	 * @param publisherType The type of publisher to read
	 * @param language The language to get
	 * @param baseDir The directory where the "2011" folder is located.
	 * @param month The month for which to get data (e.g., 01 or 02)
	 * @param day The day for which to get data (e.g., 13)
	 * @return A list of all the filenames that match the criteria
	 * @throws IOException 
	 */
	public static List<String> getFileNamesFor(SourceType publisherType, Language language, String month, String day, String baseDir) throws IOException
	{
		return getFileNamesFor(publisherType, language, month, day, new File(baseDir));
	}	
}
